#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Wjy
import json
from ConfigParser import ConfigParser

from settings import path
from core.utils import Response
from realization import Operation


class BasicsWork(object):
    """
    实现具体流程
    """

    def __init__(self, parameters, log):
        """
        :param parameters: 入参
        :param log: 日志对象
        """
        self.parameters = parameters
        self.state = 0
        self.__verify_list = ["head", "biz"]
        self.__work_list = []
        self.response = Response()
        self.log = log

    def __call__(self):
        try:
            # 如果入参是json数据转换成字典
            if isinstance(self.parameters, str):
                self.parameters = self.json
            # 入参不是字典类型数据
            if not isinstance(self.parameters, dict):
                # todo: 可以实现get请求方法
                return
            # 初始化
            self.head = self.parameters.get("head")
            self.biz = self.parameters.get("biz")
            self.method = self.parameters.get("method")

            # 可能是自营流程
            if self.head and self.biz:
                self.method = self.head["method"]
                # 从realization文件中创建相应对象
                obj = getattr(__import__(path), self.read_conf(self.method))()
                if not isinstance(obj, Operation):
                    self.log.debug("不是指定执行的类")
                    return
                # 给工作类设置日志对象
                obj.set_log(self.log)
                if obj.response:
                    self.response = obj.response

                # 追加验证方法
                if not isinstance(obj.verify_list, list):
                    self.log.debug("没有校验list")
                    return
                self.__verify_list.extend(obj.verify_list)
                # 重置验证方法
                if isinstance(obj.reload_verify_list, list):
                    self.__verify_list = obj.reload_verify_list
                for result in self.verify(obj):
                    if result:
                        return

                if not isinstance(obj.work_list, list):
                    self.log.debug("没有可执行的list")
                    return
                self.__work_list.extend(obj.work_list)
                for result in self.function(obj):
                    if result:
                        return
                return
            # todo: 其他字典入参流程
            return
        except Exception as e:
            self.log.error("错误信息描述:", e)
            self.response.code = 1
            self.response.err = "配置有误"
        finally:
            # 规定响应类型
            if isinstance(self.response, Response):
                if self.state == 0:
                    self.response.code = -1
                    self.response.err = "入参格式有误"
                self.response.err += str(self.state)
                self.response.set_head()
                return dict(self.response)
            # 自定义响应类型
            return self.response

    @property
    def json(self):
        """
        解析入参json字符串 或 返回普通字符串
        :return:
        """
        if self.parameters.startswith("{") and self.parameters.endswith("}"):
            return json.loads(self.parameters)
        elif self.parameters.startswith("{") or self.parameters.endswith("}"):
            raise ValueError("No JSON object could be decoded")
        else:
            return self.parameters

    def verify(self, obj):
        self.state = 1
        for verify in self.__verify_list:
            func = getattr(obj, verify)
            if func is None:
                self.log.error("没有配置{}方法,请检查方法".format(verify))
                raise Exception("没有配置{}方法,请检查方法".format(verify))
            yield func(getattr(self, verify, self.parameters))

    def function(self, obj):
        self.state = 2
        for work in self.__work_list:
            func = getattr(obj, work)
            if func is None:
                self.log.error("没有配置{}方法,请检查方法".format(work))
                raise Exception("没有配置{}方法,请检查方法".format(work))
            yield func()

    def read_conf(self, method):
        try:
            cf = ConfigParser()
            cf.readfp(open("../confing.conf"))
            met = cf.get("method", method)
        except Exception as e:
            self.log.error("错误信息", e)
            raise Exception("未获取到{}检查配置".format(method))
        return met
